﻿#if UNITY_EDITOR

using System;
using UnityEditor;
using UnityEngine;

namespace AI.Graph.Editor {


    public class CreateNodeEvent : GraphEvent {

        private GenericMenu m_nodeMenu;


        public override void OnProcess (Event e) {
            if (graph.controller == null) return;

            if (m_nodeMenu != null) {
                m_nodeMenu.ShowAsContext ();
                m_nodeMenu = null;
            }

            if (e.IsMouseInsideRect (canvas.unscaledRect)) {
                // need to setup here. The event is null if one generic menu opens another.
                Vector2 nodePosition = canvas.mousePosition;

                if (e.IsKeyDown (KeyCode.Space)) {
                    ShowCreateNodeMenu (nodePosition);
                    
                    e.Use ();
                }
                else if (e.IsMouseDown (MouseButton.Right)) {
                    // Check if the user clicked only on the canvas.

                    for (int i = 0; i < canvas.nodes.Length; i++) {
                        if (!canvas.nodes[i].isHidden && canvas.nodes[i].rect.Contains (canvas.mousePosition)) {
                            return;
                        }
                    }

                    GenericMenu menu = new GenericMenu ();
                    menu.AddItem (new GUIContent ("Create Node"), false, () => { ShowCreateNodeMenu (nodePosition); });
                    menu.ShowAsContext ();
                    
                    e.Use ();
                }
            }
        }


        void ShowCreateNodeMenu (Vector2 nodePosition) {
            Vector2 position = nodePosition;

            if (canvas.snapNodesOnGrid) {
                position = canvas.ConvertToSnapPosition (position);
            }

            m_nodeMenu = new GenericMenu ();

            Type[] nodeTypesToAdd = ReflectionUtility.LoadClassTypes<Node, CreateNodeMenu> ();

            for (int i = 0; i < nodeTypesToAdd.Length; i++) {
                Type nodeTypeToAdd = nodeTypesToAdd[i];

                CreateNodeMenu createNodeMenu = nodeTypeToAdd.GetAttribute<CreateNodeMenu> ();

                // Normally this cannot happen.
                if (createNodeMenu == null) {
                    Debug.LogWarning ("The node [" + nodeTypeToAdd.FullName + "] has no CreateNodeMenuAttribute");
                }
                else {
                    m_nodeMenu.AddItem (new GUIContent (createNodeMenu.path), false, () => {
                        AIController controller = graph.controller;
                        Node node = createNodeMenu.CreateNew (nodeTypeToAdd);
                        node.position = position;
                        Serializer.AddNewNodeToController (controller, node);
                        graph.Repaint ();

                        GraphUndo.Record ("Add new node [" + node.name + "]",
                            () => {
                                Serializer.RemoveNodeFromController (controller, node, false);
                                graph.Repaint ();
                            },
                            () => {
                                Serializer.RestoreNodeToController (controller, node, null);
                                graph.Repaint ();
                            });
                    });
                }
            }
        }

    }


}
#endif